import Socket from './Socket';
import Request from './Request';
import config from './config';
import User from './User';
import CmdMethods from './cmd.methods';
import observable from './state/index';
class Im {
	Socket = null;
	Http = new Request();
	User = new User();
	CmdMethods = new CmdMethods();
	config = config;
	isLogin = false;
	state = observable;
	// 初始化
	constructor() {
		if (Im.instance) {
			return Im.instance;
		}
		Im.instance = this;

	}
	//单例模式
	static getInstance() {
		if (!Im.instance) {
			Im.instance = new Im();
		}
		return Im.instance;
	}

	login(url, options) {
		return new Promise((resolve, reject) => {
			this.Http.request({
				url,
				data: options,
				method: 'POST'
			}).then(res => {
				this.state.userInfo.setUser(res.data);
				this.isLogin = true;
				resolve(res);
			}).catch(error => {
				reject(error);
			})
		})
	}
	/**
	 * @param {Object} url
	 * @param {Object} options
	 * {
			"username": "lisi",
			"nickname": "lisi",
			"password": "lisi123456",
			"password2": "lisi123456",
			"nick": "lisi",
			"userId": "lisi"
		}
	 */

	register(url, options) {
		return new Promise((resolve, reject) => {
			this.Http.request({
				url,
				data: options,
				method: 'POST'
			}).then(res => {
				this.state.userInfo.setUser(res.data);
				this.isLogin = true;
				resolve(res);
			}).catch(error => {
				reject(error);
			})
		})
	}

	logout(callback) {
		this.state.userInfo.clear();
		this.state = observable;
		callback && callback(callback)
	}

	clearUserInfo() {
		this.state.userInfo.clear();
	}

	getLogin() {
		return this.isLogin;
	}

	setUserInfo(data) {
		this.state.userInfo.setUser(data);
	}

	//修改 config
	setConfig(data) {
		this.config = {
			...this.config,
			...data
		};
	}
	//获取 config
	getConfig() {
		return this.config;
	}
	isSocketConnected() {
		return this.Socket && this.Socket.isSocketConnected();
	}
	connect(url) {
		// this.setHeartbeat()
		this.Socket = new Socket(url ||
			`${this.config.ws}/?tenant=1&username=${this.getCurrentUserNickName()}&token=${this.getToken()}`);

		this.Socket.connect();

		// 添加 WebSocket 事件监听器
		this.Socket.on('open', (event) => {
			this.setHeartbeat();
			console.log('WebSocket opened--:', event);
		});

		this.Socket.on('close', (event) => {
			console.log('WebSocket closed:', event);
		});

		this.Socket.on('error', (event) => {
			console.error('WebSocket error:', event);
		});

		this.Socket.on('message', (event) => {
			console.log('WebSocket message:', event);
			//被动接受推送消息，并主动触发相关方法
			const body = JSON.parse(event.data);
			this.Socket.emit(Math.abs(body.command), event);
			// this.onMessageCmdMethods(Math.abs(body.command), event);
		});

		this.Socket.on('maxReconnectAttemptsReached', () => {
			console.error('Maximum reconnect attempts reached. Please try again later.');
		});
	}
	/**
	 * @description 执行 CmdMethods 方法
	 * @param {Object} cmd  
	 * @param {Object} data 参数
	 * 
	 */
	executeCmdMethods(cmd, data, off = false) {
		console.log(cmd, 'executeCmdMethods')
		return new Promise((resolve, reject) => {
			if (!this.Socket) {
				console.log('未连接')
				reject();
				return;
			}
			this.CmdMethods.callCommandByCmdMethods({
				Socket: this.Socket,
				cmd
			}, data);
			const fn = (event) => {
				const data = JSON.parse(event.data);
				if (Math.abs(data.command) === Math.abs(cmd)) {
					if (!off) {
						this.Socket.off('message', fn);
					}
					resolve(data);
				}
			};
			this.Socket.on('message', fn);
		})
	}
	/**
	 * 动态添加命令配置
	 * @param {string} cmdName - 命令名称
	 * @param {Object} config - 命令配置对象，包含 cmd 和 params [参数]string可以为空数组
	 * @example addCmdMethodsConfig('getInfos',{cdm:99 , params: ['user_id']})
	 */
	addCmdMethodsConfig(name, config) {
		this.CmdMethods.addCmdMethodsConfig(name, config);
	}
	//监听主动推送消息
	onMessageCmdMethods(cmd, event) {
		this.Socket.emit(cdm, event);
	}
	//广播cmd事件
	postMeassage(cdm, callback) {
		const fn = (res) => {
			const body = JSON.parse(res.data);
			if (Math.abs(body.command) === Math.abs(cdm)) {
				callback(body);
			}
		}
		this.Socket && this.Socket.on(cdm, fn);
	}

	//获取当前用户id
	getCurrentUserId() {
		return this.state.userInfo.getUserId();
	}
	//获取当前用户头像
	getCurrentUserAvatar() {
		return this.state.userInfo.getAvatar();
	}
	//获取当前用户详细信息
	getCurrentUserInfo() {
		return this.state.userInfo.getUser();
	}

	getCurrentUserNickName() {
		return this.state.userInfo.getNickName();
	}
	getToken() {
		return this.state.userInfo.getToken();
	}

	setHeartbeat() {
		setInterval(() => {
			this.state.heartbeat = Date.now();
		}, 1000);
	}
	getHeartbeat() {
		return this.state.heartbeat;
	}
	//获取会话
	getConversation(words) {
		return this.state.conversation.get(words);
	}
	/**
	 * 获取会话cmd方法
	 * @param {Object} callback  存在回调函数不在内部处理
	 */
	getConversationCmdMethods(callback) {
		return this.state.conversation.getConversationCmdMethods(callback);
	}
	//监听会话消息推送
	postConversationMessage() {
		return this.state.conversation.postConversationMessage();
	}
	//获取未读消息数
	getUnreadCount() {
		return this.state.conversation.getUnreadCount();
	}
	//获取好友
	getFriensdsList(words) {
		return this.state.friends.get(words);
	}
	//获取好友cmd方法
	getFriendsCmdMethods() {
		return this.state.friends.getFriendsCmdMethods();
	}
	//更改产品名称 左上角文字
	setProduct(data) {
		this.state.product = data;
	}

	getProduct(data) {
		return this.state.product;
	}

	getTheme() {
		return this.state.theme;
	}

	setTheme(data) {
		this.state.theme = data;
		uni.setStorageSync('theme', data);
		// #ifdef H5
		const root = document.querySelector('html');
		root.setAttribute('data-theme', data);
		// #endif
	}

	getCurrentTab() {
		return this.state.currentTab;
	}

	setCurrentTab(data) {
		this.state.currentTab = data;
	}

	getCurrentConversationId() {
		return this.state.currentConversationId;
	}
	setCurrentConversationId(data) {
		this.state.currentConversationId = data;
	}

	/**
	 * 根据会话id获取会话
	 * @param {String} id 会话id
	 * @return {Object} 会话对象
	 */
	getConversationById(id) {
		return this.state.conversation.getConversationById(id);
	}

	/**
	 * 生成会话id
	 * @param {Function} callback 
	 */
	generateConversationId(params, callback) {
		this.state.conversation.generateConversationId(params, callback);
	}
	/**
	 * 获取消息列表
	 * @param 
	 * { "conversation": data.id,
				"maxTime": Date.now(),
				"offset": 1,
				"count": 20,
			} 参数 
	 * @param {Function} callback 
	 */
	getConversationByIdMessageList(params, callback) {
		this.state.conversation.getMessageList(params, callback)
	}

	getConversationMessageList(id, callback) {
		return this.state.conversation.getConversationMessageList(id);
	}

	clearCurrentConversationUnreadCount(id) {
		this.state.conversation.clearCurrentConversationUnreadCount(id);
	}
	clearAllUnreadCount() {
		this.state.conversation.clearAllUnreadCount();
	}

	deleteMessage(params, callback) {
		return this.state.conversation.deleteMessage(params, callback);
	}

	revokeMsg(params, callback) {
		return this.state.conversation.revokeMsg(params, callback);
	}
	getNotificationListCmdMethods(params) {
		return this.state.friends.getNotificationListCmdMethods(params);
	}

	getNotificationList(params) {
		return this.state.friends.getNotificationList(params);
	}

	addFriendInvite(params) {
		return this.state.friends.addFriendInvite(params);
	}

	acceptFriendApplication(params, callback) {
		return this.state.friends.acceptFriendApplication(params, callback);
	}

	refuseFriendApplication(params, callback) {
		return this.state.friends.refuseFriendApplication(params, callback);
	}

	readNotification(params, callback) {
		return this.state.friends.readNotification(params, callback);
	}
	
	getNotificationUnreadCount(){
		return this.state.friends.getNotificationUnreadCount();
	}
	
	searchUserList(params, callback){
		return this.state.friends.searchUserList(params, callback);
	}
	
	searchGroupList(params, callback){
		return this.state.friends.searchGroupList(params, callback);
	}
	
	getUserList(words){
		return this.state.friends.getUserList(words);
	}
	/**
	 * 获取群组在线用户列表请求; 【 在线：代表绑定群组，并且进入了群组 】
	 * @param groupId
	 * @returns {*|Promise<unknown>}
	 */
	getGroupOnlineUsersCmdMethods(params,callback){
		return this.state.friends.getGroupOnlineUsersCmdMethods(params,callback);
	}
	getGroupListCmdMethods(params,callback){
		return this.state.friends.getGroupListCmdMethods(params,callback);
	}
	getGroupList(words){
		return this.state.friends.getGroupList(words);
	}
	getGroupInfosCmdMethods(params,callback){
		return this.state.friends.getGroupInfosCmdMethods(params,callback);
	}
	getGroupInfos(){
		return this.state.friends.getGroupInfos();
	}
	//创建群聊
	createGroup(params,callback){
		return this.state.friends.createGroup(params,callback);
	}
	
	exitGroupCmdMethods(params,callback){
		return this.state.friends.exitGroupCmdMethods(params,callback);
	}
	
	exportGroupCmdMethods(params,callback){
		return this.state.friends.exportGroupCmdMethods(params,callback);
	}
	
	disBandGroupCmdMethods(params,callback){
		return this.state.friends.disBandGroupCmdMethods(params,callback);
	}
	
	addFriendInvite(params, callback){
		this.state.friends.addFriendInvite(params, callback);
	}
	addGroupInvite(params, callback){
		this.state.friends.addGroupInvite(params, callback);
	}

	init() {

	}
}

export default Im;